package com.kehutong.payfees.admin;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

import com.kehutong.common.util.Token;
import org.coraframework.authz.HasPermission;
import org.coraframework.converter.util.StringUtil;
import org.coraframework.inject.Inject;
import org.coraframework.json.JSONArray;
import org.coraframework.json.JSONObject;
import org.coraframework.mvc.MvcAction;
import org.coraframework.mvc.http.ReqMapping;
import org.coraframework.mvc.http.result.Result;
import org.coraframework.orm.jdbc.JdbcSession;
import org.coraframework.orm.jdbc.Page;
import org.coraframework.orm.jdbc.execute.entity.FindPage;
import org.coraframework.util.Objects;

import com.kehutong.payfees.entity.ChargeBill;
import com.kehutong.payfees.entity.ChargeBillItem;
import com.kehutong.payfees.enums.BillEnableState;
import com.kehutong.payfees.enums.BillOperateType;
import com.kehutong.payfees.enums.BillPaidState;
import com.kehutong.payfees.enums.BillPayMethod;
import com.kehutong.payfees.enums.ChargeAnnexType;
import com.kehutong.payfees.service.ChargeBillAnnexServiceImpl;
import com.kehutong.payfees.service.ChargeBillServiceImpl;
import com.kehutong.payfees.service.ChargeLogServiceImpl;

/**
 * Author:  peter
 * Date:    2020/8/24
 * Function:缴费中心
 */
@MvcAction
@ReqMapping("/admin/charge/center")
public class ChargeCenterAction {
    @Inject
    private ChargeBillServiceImpl chargeBillService;
    @Inject
    private ChargeLogServiceImpl chargeLogService;
    @Inject
    private ChargeBillAnnexServiceImpl chargeBillAnnexService;
    @Inject
    private JdbcSession jdbcSession;

    /**
     * 缴费中心-账单列表
     */
    @HasPermission("charge:center:view")
    @ReqMapping("/bill/page")
    public Object page(JSONObject req) {
        if (StringUtil.isBlank(req.getString("houseNo"))) {
            // 前端未选择房屋时返回空页
            return Result.success(new Page<>());
        }

        FindPage<ChargeBill> find = jdbcSession.findPage(ChargeBill.class)
                .eq(req, "houseNo")
                .eq("enableState", BillEnableState.ENABLE)
                .eq("paidState", BillPaidState.UNPAID)
                .eq("deleted", false)
                .order("communityNo", "DESC")
                .order("buildingName", "ASC")
                .order("unitName", "ASC")
                .order("floorName", "ASC")
                .order("houseName", "ASC")
                .order("billDateFrom", "ASC")
                .order("shouldPayDate", "ASC")
                .order("id", "ASC")
                .page(req);

        Page<ChargeBill> page = find.exe();

        page.getList().forEach(bill -> {
            // 缴费科目列表
            List<ChargeBillItem> items = jdbcSession.findArray(ChargeBillItem.class)
                    .eq("billNo", bill.getId())
                    .exe();
            bill.setBillItems(items);
        });

        return Result.success(page);
    }

    /**
     * 批量手动缴费
     */
    @HasPermission("charge:center:edit")
    @ReqMapping("/bills/annex/save")
    public Object saveBillsAnnex(Token token, JSONObject req) {

        JSONArray idsArr = req.getJSONArray("ids");
        if (Objects.isEmpty(idsArr)) {
            return Result.error(0, "请选择要缴费的账单");
        }

        JSONArray js = req.getJSONArray("fileIds");
        List<String> fileIds = js.stream()
                .map(String::valueOf)
                .filter(StringUtil::isNotBlank)
                .collect(Collectors.toList());
        if (fileIds.isEmpty()) {
            return Result.error(0, "上传凭证不能为空");
        }

        List<ChargeBill> bills = jdbcSession.findArray(ChargeBill.class)
                .in("id", idsArr)
                .exe();
        if (bills.size() != idsArr.size()) {
            return Result.error(0, "选择了不存在的账单");
        }
        // 校验
        for (ChargeBill bill : bills) {
            if (bill.getPaidState() != BillPaidState.UNPAID) {
                return Result.error(0, "选择了不可操作的账单");
            }
            if (bill.getEnableState() != BillEnableState.ENABLE) {
                return Result.error(0, "选择了未启用的账单");
            }
        }

        // 执行
        for (ChargeBill bill : bills) {
            chargeBillAnnexService.doInsertBillAnnex(bill.getId(), fileIds, ChargeAnnexType.PAYMENT_VOUCHER);

            bill.setPaidState(BillPaidState.PAID);
            bill.setPaidAt(LocalDateTime.now());
            bill.setPayMethod(BillPayMethod.MANUAL);
            jdbcSession.updateById(bill);

            chargeLogService.saveLog(bill.getId(), BillOperateType.MANUAL_UPDATE_PAID_STATE, req, token.getUsername(), token.getUuid());
        }

        return Result.success();
    }


}
